﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using BasketballAI.Infrastructure.GameItems;
using BasketballAI.Infrastructure.Entity;
using Algorithms;

namespace BasketballAI.Infrastructure
{
    




    public class Game
    {
        #region Structs 

            public struct LayoutItem
            {
                public int column;
                public int row;
                public Global.PartOfcourt partOfcourt;
                public Global.LocationMeaningOnCourt locationMeaning;
                public Global.RoleOnCourt roleOnCourt;
                // Constructor:
                /// <summary>
                /// 
                /// </summary>
                /// <param name="r">Item row.</param>
                /// <param name="c">Item column.</param>
                /// <param name="tp">Half of court.</param>
                /// <param name="role">role on the court.</param>
                public LayoutItem(int r, int c, Global.PartOfcourt h, Global.RoleOnCourt role)
                {
                    column = c;
                    row = r;
                    partOfcourt = h;
                    locationMeaning = Global.LocationMeaningOnCourt.NoMeaning;
                    roleOnCourt = role;
                }
            }

         
        #endregion Structs

        #region Members
        public delegate void delegatePlayerMove(IItem item ,Point lastPosition);
        public delegatePlayerMove ItemMoveEvent;
        public delegate void delegateHitTheBasket(IItem item);
        public delegateHitTheBasket onHitTheBasket;      
        public PathFinder pathfinder;// = new PathFinder(new byte[1024, 1024]);
        private IItem[,] courtMat;
        private LayoutItem[,] layoutMat;
        private Team[] teams;
        private Ball ball;
        private int shootingrangeradius;
             
        #endregion

        #region Constructors
        public Game()
        {            
            ItemMoveEvent += new delegatePlayerMove(ItemMove);            
            
        }
        #endregion

        #region Properties
        
        public IItem[,] CourtMat
        {
            get { return courtMat; }
            set { courtMat = value; }
        }
        public Team[] Teams
        {
            get { return teams; }
            set { teams = value; }
        }
        public Ball Ball
        {
            get { return ball; }
            set { ball = value; }
        }
 
        public int ShootingRangeRadius
        {
            get
            {
                Random rand = new Random();
                return rand.Next(1,10);
            }
        }

        #endregion

        #region Methods

        #region Init Methods
        //private void InitializeLayoutMat()
        //{

        //    int row = 7, col = 9;
        //    this.layoutMat = new ListLayoutItem[row, col];
        //    for (int i = 0; i < row; i++)
        //        for (int j = 0; j < col; j++)
        //            this.layoutMat[i, j].LayoutItems = new List<LayoutItem>();

        //    for (int i = 0; i < Properties.Settings.Default.CourtRows; i++)
        //        for (int j = 0; j < Properties.Settings.Default.CourtCols; j++)
        //        {
        //            //The size of the real court
        //            if (i < 19)
        //            {
        //                if (j < 16)// Half of group 1
        //                {
        //                    if (i < 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Left));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), 4].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Left));
        //                        else if (j > 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Left));
        //                    }
        //                    else if (i == 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[3, Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Left));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[3, 4].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Left));
        //                        else if (j > 18)
        //                            this.layoutMat[3, Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Left));
        //                    }
        //                    else if (i > 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Left));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), 4].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Left));
        //                        else if (j > 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Left));
        //                    }
        //                }
        //                else if (j >= 16&&j<=18)//Half line
        //                {
        //                    if (i < 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Center));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), 4].LayoutItems.Add(new LayoutItem(i, j,  Global.PartOfcourt.Center));
        //                        else if (j > 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j,  Global.PartOfcourt.Center));
        //                    }
        //                    else if (i == 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[3, Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Center));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[3, 4].LayoutItems.Add(new LayoutItem(i, j,  Global.PartOfcourt.Center));
        //                        else if (j > 18)
        //                            this.layoutMat[3, Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Center));
        //                    }
        //                    else if (i > 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Center));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), 4].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Center));
        //                        else if (j > 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Center));
        //                    }
        //                }
        //                else//j>18 , Half of group 2
        //                {
        //                    if (i < 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j, Global.PartOfcourt.Right));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), 4].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                        else if (j > 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)i / 3)), Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                    }
        //                    else if (i == 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[3, Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[3, 4].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                        else if (j > 18)
        //                            this.layoutMat[3, Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                    }
        //                    else if (i > 9)
        //                    {
        //                        if (j < 16)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), Convert.ToInt32(Math.Floor((double)j / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                        else if (j >= 16 && j <= 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), 4].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                        else if (j > 18)
        //                            this.layoutMat[Convert.ToInt32(Math.Floor((double)(i + 2) / 3)), Convert.ToInt32(Math.Floor((double)(j + 1) / 4))].LayoutItems.Add(new LayoutItem(i, j,Global.PartOfcourt.Right));
        //                    }
        //                }
        //            }
        //        }
        //}
        private void InitializeLayoutMat()
        {


            this.layoutMat = new LayoutItem[Properties.Settings.Default.CourtRows, Properties.Settings.Default.CourtCols];
          
            for (int i = 0; i < Properties.Settings.Default.CourtRows; i++)
                for (int j = 0; j < Properties.Settings.Default.CourtCols; j++)
                {
                    //The size of the real court
                    if (i < 19)
                    {
                        if (j >= 0 && j <= 7)//all role , left half
                        {
                            this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Left, Global.RoleOnCourt.AllRole);
                        }
                        else if (j >= 8 && j <= 26)//partition area.
                        {
                            if (j < 16)//left half
                            {
                                if (i >= 0 && i <= 5)//Upper Corner Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Left, Global.RoleOnCourt.UpperCornerGuard);
                                }
                                else if (i >= 6 && i <= 12)//Point Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Left, Global.RoleOnCourt.PointGuard);
                                }
                                else if (i >= 13 && i <= 18)//Lower Corner Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Left, Global.RoleOnCourt.LowerCornerGuard);
                                }
                            }
                            else if (j >= 16 && j <= 18)//Center line
                            {
                                if (i >= 0 && i <= 5)//Upper Corner Guard
                                {
                                      this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Center, Global.RoleOnCourt.UpperCornerGuard);
                                }
                                else if (i >= 6 && i <= 12)//Point Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Center, Global.RoleOnCourt.PointGuard);
                                }
                                else if (i >= 13 && i <= 18)//Lower Corner Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Center, Global.RoleOnCourt.LowerCornerGuard);
                                }

                            }
                            else //Right half
                            {
                                if (i >= 0 && i <= 5)//Upper Corner Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Right, Global.RoleOnCourt.UpperCornerGuard);
                                }
                                else if (i >= 6 && i <= 12)//Point Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Right, Global.RoleOnCourt.PointGuard);
                                }
                                else if (i >= 13 && i <= 18)//Lower Corner Guard
                                {
                                     this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Right, Global.RoleOnCourt.LowerCornerGuard);
                                }
                            }

                        }
                        else if (j >= 27 && j <= 34)//all role ,right half
                        {
                             this.layoutMat[i, j]=new LayoutItem(i, j, Global.PartOfcourt.Right, Global.RoleOnCourt.AllRole);
                        }
                    }
                }
            //ThreePoints on left court.
            this.layoutMat[0, 0].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 1].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 2].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 3].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 4].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 5].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 6].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[1, 6].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[1, 7].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[2, 7].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[2, 8].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[3, 8].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[3, 9].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[4, 9].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[4, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[5, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[6, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[7, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[8, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[9, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[10, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[11, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[12, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[13, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[14, 10].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[14, 9].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[15, 9].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[15, 8].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[16, 8].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[16, 7].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[17, 7].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[17, 6].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 6].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 5].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 4].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 3].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 2].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 1].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 0].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            //ThreePoints on right court.
            this.layoutMat[0, 34].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 33].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 32].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 31].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 30].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 29].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[0, 28].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[1, 28].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[1, 27].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[2, 27].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[2, 26].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[3, 26].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[3, 25].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[4, 25].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[4, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[5, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[6, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[7, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[8, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[9, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[10, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[11, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[12, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[13, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[14, 24].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[14, 25].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[15, 25].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[15, 26].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[16, 26].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[16, 27].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[17, 27].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[17, 28].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 28].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 29].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 30].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 31].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 32].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 33].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
            this.layoutMat[18, 34].locationMeaning = Global.LocationMeaningOnCourt.ThreePoints;
        }

        private void InitializeCourtMat()
        {
            this.courtMat = new IItem[Properties.Settings.Default.CourtRows, Properties.Settings.Default.CourtCols];
            for (int i = 0; i < Properties.Settings.Default.CourtRows; i++)
            {
                for (int j = 0; j < Properties.Settings.Default.CourtCols; j++)
                {
                    if (i < 19)
                    {
                        courtMat[i, j] = new IItem();
                        courtMat[i, j].AStarPosition = Global.AstarPosition.EmptyPosition;
                    }
                    else
                    {
                        courtMat[i, j] = new IItem();
                        courtMat[i, j].AStarPosition = Global.AstarPosition.TakenPosition;
                    }
                }
            }
        }
        #endregion Init Methods

        public void StartGame()
        {
            InitializeLayoutMat();
            InitializeCourtMat();
            this.teams = new Team[2];
            // Setting ball initial position
            this.ball = new Ball(new Point(Convert.ToInt32(Properties.Settings.Default.BallInitSpread.Split(',')[0]), Convert.ToInt32(Properties.Settings.Default.BallInitSpread.Split(',')[1])), Global.AstarPosition.EmptyPosition);            
            String[] team1PlayerNames;
            String[] team2PlayerNames;
            Player[] team1Players = new Player[Properties.Settings.Default.NumOfPlayersInTeam];
            Player[] team2Players = new Player[Properties.Settings.Default.NumOfPlayersInTeam];
            String[] Group1InitStrings;
            String[] Group2InitStrings;           
            try
            {
                // Creating players
                Group1InitStrings = Properties.Settings.Default.Group1InitSpread.Split('|');
                Group2InitStrings = Properties.Settings.Default.Group2InitSpread.Split('|');
                team1PlayerNames = Properties.Settings.Default.Team1PlayerNames.Split(',');
                team2PlayerNames = Properties.Settings.Default.Team2PlayerNames.Split(',');
                for (int i = 0; i < Properties.Settings.Default.NumOfPlayersInTeam; i++)
                {
                    if (Group1InitStrings[i].Split(',')[2] == "PointGuard")
                    {
                        
                        team1Players[i] = new Player(new Point(Convert.ToInt32(Group1InitStrings[i].Split(',')[0]), Convert.ToInt32(Group1InitStrings[i].Split(',')[1])), team1PlayerNames[i], Global.AstarPosition.TakenPosition, 0, Properties.Resources.greenTeam,Global.RoleOnCourt.PointGuard);
                        team2Players[i] = new Player(new Point(Convert.ToInt32(Group2InitStrings[i].Split(',')[0]), Convert.ToInt32(Group2InitStrings[i].Split(',')[1])), team2PlayerNames[i], Global.AstarPosition.TakenPosition, 1, Properties.Resources.redTeam, Global.RoleOnCourt.PointGuard);
                    }
                    else if (Group1InitStrings[i].Split(',')[2] == "UpperCornerGuard")
                    {
                        team1Players[i] = new Player(new Point(Convert.ToInt32(Group1InitStrings[i].Split(',')[0]), Convert.ToInt32(Group1InitStrings[i].Split(',')[1])), team1PlayerNames[i], Global.AstarPosition.TakenPosition, 0, Properties.Resources.greenTeam, Global.RoleOnCourt.UpperCornerGuard);
                        team2Players[i] = new Player(new Point(Convert.ToInt32(Group2InitStrings[i].Split(',')[0]), Convert.ToInt32(Group2InitStrings[i].Split(',')[1])), team2PlayerNames[i], Global.AstarPosition.TakenPosition, 1, Properties.Resources.redTeam, Global.RoleOnCourt.UpperCornerGuard);
                    }
                    else if (Group1InitStrings[i].Split(',')[2] == "LowerCornerGuard")
                    {
                        team1Players[i] = new Player(new Point(Convert.ToInt32(Group1InitStrings[i].Split(',')[0]), Convert.ToInt32(Group1InitStrings[i].Split(',')[1])), team1PlayerNames[i], Global.AstarPosition.TakenPosition, 0, Properties.Resources.greenTeam, Global.RoleOnCourt.LowerCornerGuard);
                        team2Players[i] = new Player(new Point(Convert.ToInt32(Group2InitStrings[i].Split(',')[0]), Convert.ToInt32(Group2InitStrings[i].Split(',')[1])), team2PlayerNames[i], Global.AstarPosition.TakenPosition, 1, Properties.Resources.redTeam, Global.RoleOnCourt.LowerCornerGuard);
 
                    }
                    team1Players[i].GuardOnPlayer = team2Players[i];
                    team2Players[i].GuardOnPlayer = team1Players[i];
                }                
                // Creating teams
                this.teams[0] = new Team(Properties.Settings.Default.Team1Name, team1Players);
                this.teams[1] = new Team(Properties.Settings.Default.Team2Name, team2Players);
                // Setting baskets initial position
                this.teams[0].TargetBasket = new Basket(new Point(Convert.ToInt32(Properties.Settings.Default.leftBasketInitSpread.Split(',')[0]), Convert.ToInt32(Properties.Settings.Default.leftBasketInitSpread.Split(',')[1])), Global.AstarPosition.EmptyPosition);
                this.teams[1].TargetBasket = new Basket(new Point(Convert.ToInt32(Properties.Settings.Default.rightBasketInitSpread.Split(',')[0]), Convert.ToInt32(Properties.Settings.Default.rightBasketInitSpread.Split(',')[1])), Global.AstarPosition.EmptyPosition);
                // Set players initial position on court matrix.
                foreach (Player p in team1Players)
                    CourtMat[p.PositionOnCourt.X,p.PositionOnCourt.Y] = p;                
                foreach (Player p in team2Players)
                    CourtMat[p.PositionOnCourt.X,p.PositionOnCourt.Y] = p;
                //  Set ball initial position on court matrix.
                //CourtMat[this.ball.PositionOnCourt.Y,this.ball.PositionOnCourt.X] = this.ball;
                //  Set left basket initial position on court matrix.
                CourtMat[this.teams[0].TargetBasket.PositionOnCourt.X, this.teams[0].TargetBasket.PositionOnCourt.Y] = this.teams[0].TargetBasket;
                //  Set right basket initial position on court matrix.
                CourtMat[this.teams[1].TargetBasket.PositionOnCourt.X, this.teams[1].TargetBasket.PositionOnCourt.Y] = this.teams[1].TargetBasket;
                //  Initialize the game: Random decide who gets the ball
                Random rand = new Random();
                //if (rand.Next(2) == 1)
                //{
                //    this.teams[1].TeamStatus = Global.TeamStatus.Offence;
                //    this.teams[0].TeamStatus = Global.TeamStatus.Defence;                   
                //    //this.teams[1].TeamPlayers[0].HasBall = true;
                //}
                //else
                //{
                    this.teams[0].TeamPlayers[0].HasBall = true;
                    this.teams[0].TeamStatus = Global.TeamStatus.Offence;
                    this.teams[1].TeamStatus = Global.TeamStatus.Defence;                  
                    //this.teams[0].TeamPlayers[0].HasBall = true;
              //  }                

            }
            catch (Exception e)
            {
                MessageBox.Show("Invalid initial configuration parameters (Game.StartGame) Error:" + e.Message);
            }
            pathfinder = new PathFinder(courtMat);

            //this.Teams[0].TeamPlayers[0].DestinationPath = pathfinder.FindPath(this.Teams[0].TeamPlayers[0].PositionOnCourt, new Point(9, 0));
            //this.Teams[1].TeamPlayers[1].DestinationPath = pathfinder.FindPath(this.Teams[1].TeamPlayers[1].PositionOnCourt, new Point (9,19));
            //this.teams[0].TeamPlayers[0].hasClearPathBetweenPoints(new Point(20, 11), new Point(20, 7));
        }

        private void EndGame()
        {
        }
      
        

       
   
       
        /// <summary>
        /// Finds route between 2 points
        /// </summary>
        /// <param name="start">Start point</param>
        /// <param name="end">End point</param>
        /// <returns></returns>
        public List<PathFinderNode> FindPath(Point start, Point end)
        {           
            return pathfinder.FindPath(start, end);
        }
    
        /// <summary>
        /// Get position on court by meaning.
        /// </summary>
        /// <param name="meaning">Meaning required,"no meaning" - get full area.</param>
        /// <param name="partOfcourt">Half of court required,Left - For Left court , Right - For 
        /// right court , Center - For cente court , All - For all court.</param>
        /// <param name="role">Role player.</param>   
        /// <param name="position">Position player.</param>   
        /// <param name="radius">Radius of movement (in the squares on the court matrix), -1 - max radius.</param>   
        /// <returns>Point on courtMat , if failed return empty point.</returns>
        public Point FindPointInAreaByMeaning(Global.LocationMeaningOnCourt meaning, Global.PartOfcourt partOfcourt, Global.RoleOnCourt role, Point position, int radius)
        {
            Point returnPoint;
            List<Point> tmpList = new List<Point>();                      
                foreach (LayoutItem item in this.layoutMat)
                {
                    if (item.partOfcourt == partOfcourt || partOfcourt== Global.PartOfcourt.All)
                    {
                        if (item.roleOnCourt == role || item.roleOnCourt==Global.RoleOnCourt.AllRole)
                        {
                            if (meaning != Global.LocationMeaningOnCourt.NoMeaning)
                            {                                
                                if (item.locationMeaning == meaning)
                                {
                                    if (radius == -1)
                                    {
                                        tmpList.Add(new Point(item.row, item.column));
                                    }
                                    else//check radius
                                    {
                                        if (item.row >= position.X - radius && item.row <= position.X + radius
                                            && item.column >= position.Y - radius && item.column <= position.Y+radius)//row and column in radius
                                        {
                                            tmpList.Add(new Point(item.row, item.column));
 
                                        } 
                                    }
                                }                                
                            }
                            else
                            {
                                if (radius == -1)
                                {
                                    tmpList.Add(new Point(item.row, item.column));
                                }
                                else//check radius
                                {
                                    if (item.row >= (position.X - radius) && item.row <= (position.X + radius)
                                        && item.column >= (position.Y - radius) && item.column <= (position.Y + radius))//row and column in radius
                                    {
                                        tmpList.Add(new Point(item.row, item.column));

                                    }
                                }
                            }
                        }
                    }
                }
            
            if (tmpList.Count > 0)
                    {
                        Random rand = new Random();
                        int randIndex = rand.Next(tmpList.Count);
                        returnPoint = new Point(tmpList[randIndex].X, tmpList[randIndex].Y);
                    }
            else
                returnPoint = Point.Empty;
            return returnPoint;
        }
        #region Halp Methods
      
        /// <summary>
        /// Check if the new position is empty.
        /// </summary>
        /// <param name="p">new position on court mat.</param>
        /// <returns>true if empty else false.</returns>
        public bool isCourtLocationEmpty(Point p)
        {
            if (this.courtMat[p.X, p.Y] is Player)
                return false;
            else
                return true;
        }
        /// <summary>
        /// Convert  position in the matrix to the position on screen.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public Point ConvertPositionFromMat2Pix(Point p)
        {
            Point rp = new Point(0, 0);
            if (p != null)
            {
                rp.Y = p.X * 20 + 40;
                rp.X = p.Y * 20 + 40;
            }
            return rp;
        }
        /// <summary>
        /// Convert  position from the position on screen to matrix.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public Point ConvertPositionFromPix2Mat(Point p)
        {
            Point rp = new Point(0, 0);
            if (p != null)
            {
                rp.Y = (p.X - 40) / 20;
                rp.X = (p.Y - 40) / 20;
            }
            return rp;
        }  

        #endregion Halp Methods
        #endregion

        #region Events

        /// <summary>
        /// Function calls when item moves on the court.
        /// </summary>
        /// <param name="p">Item that moves</param>
        public void ItemMove(IItem item, Point lastPosition)
        {           
            if (item is Player)
            {
                if (!lastPosition.IsEmpty)
                {                    
                    courtMat[lastPosition.X, lastPosition.Y] = new IItem();
                    courtMat[lastPosition.X, lastPosition.Y].AStarPosition = Global.AstarPosition.EmptyPosition;
                }
                //if (CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y] is Ball)
                //{
                //    ((Player)item).HasBall = true;
                //}             
                CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y] = item;
                
            }
            else if (item is Ball)
            
            {

                if (CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y] is Basket)
                {

                    if (this.onHitTheBasket != null)
                        onHitTheBasket(CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y]);
                }
                else if (CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y] is Player)
                {
                    ((Player)CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y]).HasBall = true;
                    
                    if(((Player)CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y]).AmIinTeam(Global.Game.Teams[0]))
                    {
                        Global.Game.Teams[0].TeamStatus = Global.TeamStatus.Offence;
                        Global.Game.Teams[1].TeamStatus = Global.TeamStatus.Defence;
                    }
                    else
                    {
                        Global.Game.Teams[1].TeamStatus = Global.TeamStatus.Offence;
                        Global.Game.Teams[0].TeamStatus = Global.TeamStatus.Defence;
                    }                    
                }                
                else
                {
                    if (!lastPosition.IsEmpty && lastPosition != item.PositionOnCourt)
                    {
                        if (CourtMat[lastPosition.X, lastPosition.Y] is Player)
                            ((Player)CourtMat[lastPosition.X, lastPosition.Y]).HasBall = false;
                        else
                        {
                            courtMat[lastPosition.X, lastPosition.Y] = new IItem();
                            courtMat[lastPosition.X, lastPosition.Y].AStarPosition = Global.AstarPosition.EmptyPosition;
                        }
                    }


                     CourtMat[item.PositionOnCourt.X, item.PositionOnCourt.Y] = item;
                    
                }

               
            }
           
        }

        #endregion


    }
}
